import { Injectable, InjectByName, InjectFactory } from '../../decorators/inject';
import { NTableEvent } from '../../types/cors';
import { IValueString, IValueFormula } from './types';
import { ITableDatas } from '../../cors/table-datas.interface';
import { TableFormula } from './table-formula';
import { TAllTypes, IAllPosition } from '../../utils/formula/types';
import { isContainRange } from '../../utils/tools';
import { Dependence } from './dependence';

@Injectable()
export class ValueFormula implements IValueFormula {
  public type: 'value' = 'value';
  // @ts-ignore
  public dataType: 'string'| 'number'|'boolean'|'error' = 'string';
  public displayValue: string | number | boolean = '';
  public value: string | number | boolean;
  public dependence: Dependence
  constructor(
    @InjectByName('TableEvent') protected tableEvent: NTableEvent.IDataEvent,
    @InjectByName('TableDatas') protected tableDatas: ITableDatas,
    @InjectFactory() protected factory: (args: any) => any
  ) {

  }
  public init() {
    this.dependence = this.factory(Dependence);
  }
  public update(val: string) {
    let formula = this.factory(TableFormula) as TableFormula;
    let result = formula.updateFormulaStr(val.replace('=', ''), (arr: TAllTypes[]) => {
      let positionArr = arr.filter(item => item.type === 'position' || item.type === 'rowPosition' || item.type === 'colPosition');

      return true;
    });
    if(result.type === 'error') {
      this.dataType = 'error';
      this.value = '';
      this.displayValue = result.toString();
      return;
    }
    // @ts-ignore
    if(result.type === 'value') {
      // @ts-ignore
      this.dataType = result.dataType as 'string'| 'number'|'boolean';
      // @ts-ignore
      this.value = result.value as string|number|boolean;
      return;
    }
    console.error(result);
    throw new Error('unexpect!');
  }
  public getOriginDataType() {
    return 'formula';
  }
  public toString() {
    return this.value.toString();
  }
  public getValue() {
    return this.displayValue;
  }
  public destroy() {
    this.dependence.distory();
  }
}